var WFWindow = new Class({
    Implements: [Options, Events],
    options: {
        name: 'sample',
        baseName: '',
        title: 'sample',
        btnSettings: true,
        btnTimer: false,
        btnRefresh: true,
        btnHelp: true,
        btnMaximize: false,
        showRefreshInMaximizeScreen:false,
        btnClose: true,
        loadCSS: false,
        serverSetting: false,
        supportServerTypes: [],
        useComponents:[],
        defaultWidgetHeight: wfc_defaultWidgetHeight
    },
    saveServer: {},
    serverList: [],
    widgetPath: '',
    objectBox: {},
    boxHD: {},
    boxBD: {},
    boxFT: {},
    boxTitle: {},
    boxButton: {},
    settingModal: {},
    maximizeModal: {},
    intIconNumber: 0,
    intIconWidth: 18,
    components: [],
    settingModalOption: {
        title: '',
        content: '',
        callBack: function(){}.bind(this)
    },
    maximizeModalOption: {
        mainContent: '<div></div>',
        bottomContent: '<div id="close_maximizeScreen" class="ui-button close clearfix"><div class="left"></div><div class="mid">'+lang.label('close')+'</div></div>',
        callBack: function(){
            $$('.modalContent .close').addEvent('click',function(e){
                this.maximizeModal.close();
            }.bind(this));

            $$('.modalTitle .refresh').addEvent('click',function(e){
                alert('refresh maximize screen');
            }.bind(this));
        },
        callBackBeforeClose: function(){},
        callBackAfterResize: function(){}
    },
    includeScript: [],
    includeScriptTimes: 0,
    id: 0,
    myDrag: {},
    arrServerSettingRequest: [],
    componentNumber: 0,
    pageNumber: 0,
    widgetInfo:{},
    /*
     * modTmpDynamicLoadScript is to store tmp element <span id="mod_tmp_[wid]"></span> in order to fix dynamic load order
     * Problem : 
     * Tab1 got modA, modB, modC in order
     * modA/module.js got property includeScript: ['a.js','b.js']
     * modB & modC/module.js includeScript: [] is empty
     * 
     * If load Tab1
     * The order will outcome modB, modC, modA, the correct order should be modA, modB, modC
     * because modA includeScript is asynchronous event
     * before modA onload a.js & b.js, modB and modC will continue render to UI,
     * after modA onload a.js & b.js, modA will inject to bottom of box, and the order will be modB, modC, modA
     * 
     * Solution:
     * before modA onload a.js & b.js, WGF will create  <span id="mod_tmp_[wid]"></span> into the box
     * after modA onload a.js & b.js, <span id="mod_tmp_[wid]"></span> will replace to modA 
     */
    modTmpDynamicLoadScript: {},
    initialize: function(position,id,showMin,showClose,showSetting,showHelp,allowDrag,uniqueCss,pageNumber,order,widget_key){
        if(this.options.baseName){
            this.widgetPath = homeBase+WP_WEBROOT_NO_SLASH+'/widgetBase'+'/'+this.options.baseName;
        }
        else{
            this.widgetPath = homeBase+WF.util.getWidgetPath(this.options.name)+'/'+this.options.name;
        }
        //dynamic include script
        this.id = id;
        this.widget_key = widget_key;
        this.position = position;
        this.pageNumber = pageNumber;
        this.widgetInfo = {"pageNumber":pageNumber,"widgetName":this.options.name};
        this.includeScriptFullPath = [];
        if(this.includeScript && this.includeScript.length){ // If got includeScript
        	for(var i=0,j=this.includeScript.length;i<j;i++){
        		this.includeScriptFullPath[this.includeScriptFullPath.length] = this.widgetPath+'/inc/'+this.includeScript[i];
        	}
            if(intAddWidgetNumber > 0){
                this.modTmpDynamicLoadScript['mod_tmp_'+this.id] = new Element('div', {'id':'mod_tmp_'+this.id}).injectTop(this.getPosition(this.position));
            }else{
        	this.modTmpDynamicLoadScript['mod_tmp_'+this.id] = new Element('div', {'id':'mod_tmp_'+this.id}).injectInside(this.getPosition(this.position));
            }
			this.dynamicLoadScript();
        }
        else{
            this.renderInside(this.getPosition(this.position));
        }
    },
	dynamicLoadScript: function(){
		require(this.includeScriptFullPath, function () {
			this.renderReplaces(this.modTmpDynamicLoadScript['mod_tmp_'+this.id]);
		}.bind(this));
	},
    includeScriptCallback: function(){
        this.includeScriptTimes++;
        if(this.includeScriptTimes === this.includeScript.length){
            this.renderInside(this.getPosition(this.position));
        }
    },
    cancelRequest: function(){
        this.arrServerSettingRequest.each(function(item,index){
            item.cancel();
        });
    },
    getPosition: function(position){
        var dPosition = $$('#canvas'+wfc_mainScreen.currActive+' .layout .box')[position];
        return dPosition;
    },
    renderContent: function(){
        this.onFinish();
    },
    onFinish: function(){
    },
    onWidgetResize: function(event){
		var width = this.boxHD.getSize().x - this.boxButton.getSize().x;
		this.boxTitle.setStyle('width',width);
    },
    onContentresize: function(event){
    },
    renderInside: function(position){
    	this.render(position);
    },
    renderReplaces: function(position){
    	this.render(position,'replaces');
    },
    render: function(position, strInjectType){
        var savedSettings = this.getData(this.id); // get the saved settings full string
        var miscData = this.getMiscData(this.id);

        if(this.options.serverSetting){
            this.saveServer = Object.append({}, custom_options.default_reportserver||{});
            for (var i=0,j=miscData.length;i<j;++i) {
                if (miscData[i].id === 'dataSources') {
                    this._buildSaveServer(miscData[i].data);
                    break;
                }
            }
        }

        var widgetParam;
        if (this.getParam(this.id)){
            var widgetParam = htmlentities('['+JSON.encode(this.getParam(this.id))+']');
        }else{
            var widgetParam = '';
        }

        var widgetSetting;
        if (savedSettings){
            var widgetSetting = htmlentities('['+JSON.encode(savedSettings)+']');
        }else{
            var widgetSetting = '';
        }

        this.objectBox = new Element('table', {
            'class':'widget ' + this.options.name,
            'id':'sbox'+this.id,
            'data':'{"name":"'+this.options.name+'","wid":"'+this.id+'","widget_key":"'+htmlentities(this.widget_key)+
                   '","param":"'+widgetParam+'","data":"'+widgetSetting+'"}',
            'dHeight':this.options.defaultWidgetHeight
        });
        if(strInjectType === undefined){
            if(intAddWidgetNumber > 0){
                this.objectBox.injectTop(position);
            }else{
        	this.objectBox.injectInside(position);
            }
        }else{
        	switch(strInjectType){
        		case 'replaces':
        			this.objectBox.replaces(position);
        		break;
        		default:
        			this.objectBox.injectInside(position);
        		break;
        	}
        }
        
        
        this.objectBoxTbody = new Element('tbody').injectInside(this.objectBox);

        this.objectBox.addEvent('widget_resize',this.onContentresize.bind(this));
		//this.objectBox.addEvent('widget_resize',this.onWidgetResize.bind(this));

        this.boxHDRow = new Element('tr', {'class':'hd','id':'widget_hd'+this.id}).injectInside(this.objectBoxTbody);
        this.boxHDRow.addEvents({
            mousedown: this.onDragWidget.bind(this)
        });
        new Element('td', {'class':'left'}).injectInside(this.boxHDRow);
        this.boxHD = new Element('td', {'class':'mid'}).injectInside(this.boxHDRow);
       
        
        new Element('td', {'class':'right'}).injectInside(this.boxHDRow);
        this.boxTitle = new Element('div', {'class':'title ellipsis','styles':{'width':intWidgetTitleEllipsisDefaultWidth},'html':this.options.title,'title':html_entity_decode(this.options.title)}).injectInside(this.boxHD);

        this.boxButton = new Element('div', {'class':'icon'}).injectInside(this.boxHD);


        // grouping actions into drop-down menu
        if (this.options.serverSetting) {
            this.addFunctionItem('btn_server_setting',this.onClickServerSettings.bind(this), lang.label('widget_btn_server_setting'));
        }
        if(this.options.btnSettings){
            this.addFunctionItem('btn_setting',this.onClickSettings.bind(this), lang.label('widget_btn_setting'));
        }
        
        if(this.options.btnTimer){
            this.addFunctionItem('btn_timer',this.onClickTimer.bind(this), lang.label('widget_btn_timer'));
            
                var timer = function(context) {
                    return function() {
                        clearTimeout(timer.tId);
                        
                        if (!timer.timer_on || !timer.timer_unit_interval || typeof context.timerCallback !== 'function') {
                            return;
                        }
                        timer.tId = setTimeout(function() {
                            context.timerCallback();
                            timer();
                        },timer.timer_unit_interval);
                    }
                }(this);
            
            // default value of timer
            // if db is empty
            //     get value from objTimerConfig if defined
            //        - timerOnDefaultSelected: '1',
    		//        - timerUnitDefaultSelected: 'minutes',
    		//        - timerUnitIntervalDefaultSelected: '2'
            //     else
            //        - Get index 0 of timerUnit
            //        - Get index 0 of timerUnitInterval.timerUnit
            // else
            //    get value of db
            timer.timer_on = this.objTimerConfig.defaultConfig !== undefined && this.objTimerConfig.defaultConfig.timerOnDefaultSelected !== undefined ? this.objTimerConfig.defaultConfig.timerOnDefaultSelected : 0;
            timer.timer_unit = this._getTimerUnitDefault();
            timer.timer_unit_interval = this.objTimerConfig.defaultConfig !== undefined && this.objTimerConfig.defaultConfig.timerUnitIntervalDefaultSelected ? this._timerIntervalTransformToMiliseconds(timer.timer_unit,this.objTimerConfig.defaultConfig.timerUnitIntervalDefaultSelected) : this._timerIntervalTransformToMiliseconds(timer.timer_unit,this.objTimerConfig.defaultConfig.timerUnitInterval[timer.timer_unit][0]);
            timer.tId = 0;
            
            this.objectBox.timer = timer;
        }
        
        if(this.options.btnMaximize){
            this.addFunctionItem('btn_maximize_screen',this.onClickMaximizeScreen.bind(this), lang.label('widget_btn_maximize_screen'));
        }
        if(this.options.btnHelp){
            this.addFunctionItem('btn_help',this.onClickHelp.bind(this), lang.label('widget_btn_help_page'));
        }
        
        if(this.options.btnClose){
            var dCloseButton = this.addFunctionItem('btn_close',this.onClickClose.bind(this), lang.labelText('widget_btn_close'));
            dCloseButton.setProperty('wid', this.id);
        }

        // count the number of icon have to render in Window.js,
        // improve the performance
        // set the icon div width only reach intTotalIconHaveToSet
        //var intTotalIconHaveToSet = Number(this.options.btnClose)+Number(this.options.btnHelp)+Number(this.options.btnRefresh)+Number(this.options.btnSettings)+Number(this.options.btnTimer)+Number(this.options.btnMaximize) + 1;
        var intTotalIconHaveToSet;
        
        if(this.options.btnRefresh){
            this.addButton('btn_refresh',this.onClickRefresh.bind(this), lang.label('widget_btn_refresh'), intTotalIconHaveToSet);
        }        
        
        var iTotalActionItem = this.boxHD.getElements('.func-list-cont li').length;
        
        if (iTotalActionItem > 0) {
            var dFuncListCont = this.boxHD.getElement('.func-list-cont'),
                fHideFuncListCont = function() {
                    $(document).removeEvent('click', fHideFuncListCont);
                    dFuncListCont.setStyle('visibility', 'hidden');
                };
            
            this.addButton('btn_func_list', function() {
                if (dFuncListCont.getStyle('visibility') === 'visible') {
                    fHideFuncListCont();
                    return;
                }
            
                var iTotalHeight = parseInt(dFuncListCont.getStyle('height')),
                    iH = 0,
                    quot = 0,
                    iMargin = 7;
                $(document).addEvent('click', fHideFuncListCont);
                
                dFuncListCont.setStyles({
                    height: '0px',
                    visibility: 'visible'
                });
                
                iH = quot = Math.floor(iTotalHeight / iMargin);
                
                setTimeout(function() {
                    dFuncListCont.setStyle('height', iH + 'px');
                    if (iH < iTotalHeight) {
                        iH += quot;
                        if (iH >= iTotalHeight) {
                            iH = iTotalHeight;
                        }
                        setTimeout(arguments.callee, 10);
                    }
                }, 10);
                
            }, lang.labelText('btn_more_options'));
            
            this.boxHD.getElement('.btn_func_list').addEvent('click',function() {
                WF.util.stopSlideShow();
            });            
        }

        /*
        if(this.options.btnClose){
            var dCloseButton = this.addButton('btn_close',this.onClickClose.bind(this), lang.labelText('widget_btn_close'), intTotalIconHaveToSet);
            dCloseButton.setProperty('wid', this.id);
        }
        */

        this.boxBDRow = new Element('tr', {'class':'bd'}).injectInside(this.objectBoxTbody);
        new Element('td', {'class':'left'}).injectInside(this.boxBDRow);
        this.boxContent = new Element('td', {'class':'mid'}).injectInside(this.boxBDRow);
        this.widgetContent = new Element('div', {'class':'widgetContent'}).injectInside(this.boxContent);
        this.boxBD = new Element('div', {'class':'boxBD'}).injectInside(this.widgetContent);

        WF.util.setWidgetContentWidth(this.objectBox);
        
        if (!wfc_widgetXScrollbar){
            this.widgetContent.setStyle('overflow-x', 'hidden');
        }

        new Element('td', {'class':'right'}).injectInside(this.boxBDRow);

        this.boxFTRow = new Element('tr', {'class':'ft'}).injectInside(this.objectBoxTbody);
        new Element('td', {'class':'left'}).injectInside(this.boxFTRow);
        this.boxFT = new Element('td', {'class':'mid'}).injectInside(this.boxFTRow);
        new Element('td', {'class':'right'}).injectInside(this.boxFTRow);

        //Add old contentBox
        if(typeof(this.boxObject) == 'object'){
            this.contentBox = new Element('div', {'id':'insetdiv2'+this.myid,'class':  'window_content'}).injectInside(this.boxBD);
        }
        if(this.options.loadCSS && !wfc_cssloaded.contains(this.options.name)){
            if(this.options.baseName){
                if(!wfc_cssloaded.contains(this.options.baseName)){
                    Asset.css(this.widgetPath+'/'+this.options.baseName+'.css');
                    wfc_cssloaded.push(this.options.baseName);
                }
            }
            else{
                Asset.css(this.widgetPath+'/'+this.options.name+'.css');
                wfc_cssloaded.push(this.options.name);
            }
        }
        
		this.handleMiscData(miscData);
        this.renderContent();
        
        if (this.objectBox.timer && this.objectBox.timer.timer_on && this.objectBox.timer.timer_unit && this.objectBox.timer.timer_unit_interval) {
            this.objectBox.timer();
        }
        
    },
    _getTimerUnitDefault: function(){
    	return this.objTimerConfig.defaultConfig !== undefined && this.objTimerConfig.defaultConfig.timerUnitDefaultSelected ? this.objTimerConfig.defaultConfig.timerUnitDefaultSelected : this.objTimerConfig.defaultConfig.timerUnit[0];
    },
    addFunctionItem : function (btnName, fnName, btnTip) {
        var dFuncListCont = this.boxHD.getElement('.func-list-cont');

        if (!dFuncListCont) {
            dFuncListCont = new Element('div', {
                'class': 'func-list-cont',
                html: '<ul class="func-list"></ul>'
            }).inject(this.boxHD);            
        }
    
        var dItem = new Element('li', {
            'class': btnName + ' func-list-item',
            html: btnTip,
            id: btnName + '-'+this.id
        }).inject(dFuncListCont.getElement('.func-list'));
        
        dItem.addEvents({
            'click': function(ev) {
                this.blur();
                fnName(ev);
            }
        });
        return dItem;        
    },
    addButton: function(btnName, fnName, btnTip){
        /*
    	if (intTotalIconHaveToSet === undefined) { //only set width to DOM if trigger addButton in module.js
    	this.intIconNumber++;
    	//In order to Fix IE7 error, div.icon must set specify width
	    	this.boxButton.setStyles({'width':this.intIconNumber*this.intIconWidth});
    	} else { //trigger addButton in Window.js
    		this.intIconNumber++;
    		if(this.intIconNumber === intTotalIconHaveToSet){
    			this.boxButton.setStyles({'width':this.intIconNumber*this.intIconWidth});
    		}
    	}
        */

        /*
        if (trimString(btnTip)){
            var dButton = new Element('a', {'class':btnName,'href':'#','id':btnName+'_'+this.id, 'title': btnTip}).injectInside(this.boxButton);
        } else {
            var dButton = new Element('a', {'class':btnName,'href':'#','id':btnName+'_'+this.id}).injectInside(this.boxButton);
        }
        */
        var dButton = new Element('a', {
            'class': btnName,
            'href': '#',
            'id': btnName+'_'+this.id,
            'title': trimString(btnTip) ? btnTip : ''
        }).inject(this.boxButton);
        
        dButton.addEvents({
            'click': function(event){
                event.preventDefault();
                event.stopPropagation();
                this.blur();
                if (this.get('class') !== 'btn_func_list') {
                    var el = this.getParent('table.widget').getElement('div.func-list-cont');
                    if (el) {
                        el.setStyle('visibility', 'hidden');
                    }
                }
                fnName(event);
            },
            'mousedown': function(event){
                event.stopPropagation();
            },
            'mouseup': function(event){
                event.stopPropagation();
            }
        });
        return dButton;
    },
    onClickServerSettings : function (ev) {
        WF.util.stopSlideShow();
        this.serverSetting();
    },
    onClickSettings: function(event){
        event.preventDefault();
        WF.util.stopSlideShow();
        
        if (typeof this.boxObject === 'object') {
                this.settingModal = new WFModal({title:this.options.title,content:'',callBack:this.MochaModalCallBack.bind(this)}, this);
        } else {
            this.settingModal = new WFModal({title:this.settingModalOption.title,content:this.settingModalOption.content,callBack:this.settingModalOption.callBack.bind(this)});
        }
    },
    onClickMaximizeScreen: function(event){
        event.preventDefault();
        WF.util.stopSlideShow();
        this.maximizeModal = new WFModal({className:'modalMaximizeScreen',title:this.options.title,maximize:true,showRefresh:this.options.showRefreshInMaximizeScreen,content:'<div id="widgetMaximizeScreen"><div class="hd">'+this.maximizeModalOption.mainContent+'</div><div class="bd clearfix">'+this.maximizeModalOption.bottomContent+"</div></div>",callBack:this.maximizeModalOption.callBack.bind(this),callBackBeforeClose: this.maximizeModalOption.callBackBeforeClose.bind(this),callBackAfterResize:this.maximizeModalOption.callBackAfterResize.bind(this),eventPosition:20});
    },
    onClickTimer: function(event) {
        event.preventDefault();
        WF.util.stopSlideShow();
        var strHtmlTimerUnitOption = this._getHtmlTimerUnitOption(this.objTimerConfig.defaultConfig.timerUnit, this.objTimerConfig.defaultConfig.timerUnit[0]),
            strHtmlTimerUnitIntervalOption = this._getHtmlTimerUnitIntervalOption(this.objTimerConfig.defaultConfig.timerUnitInterval[this.objTimerConfig.defaultConfig.timerUnit[0]], this.objTimerConfig.defaultConfig.timerUnit[0]);
            strHTMLTimerModal = [
                    '<div id="timerSetting_message"></div>',
                    '<div class="hd">',
                    '       <table class="timerTable" id="timerTable">',
                    '           <tbody>',
                    '               <tr>',
                    '                   <td><input type="checkbox" name="timer_on" id="timer_on" class="timer_on" value="1" /> '+lang.label('enable_timer')+'</td>',
                    '               </tr>',
                    '               <tr>',
                    '                   <td class="blockRefreshSettingsFrequency">'+lang.label('frequency_timer')+'<select name="timer_unit_interval" id="timer_unit_interval" class="timer_unit_interval">',
                                                  strHtmlTimerUnitIntervalOption,
                    //'                           <option value="1">1</option>',
                    //'                           <option value="2">2</option>',
                    //'                           <option value="3">3</option>',
                    //'                           <option value="4">4</option>',
                    '                       </select>',
                    '                       <select name="timer_unit" id="timer_unit" class="timer_unit">',
                                                  strHtmlTimerUnitOption,
                    '                           <option value="seconds">seconds</option>',
                    //'                           <option value="minutes">minutes</option>',
                    //'                           <option value="hours">hours</option>',
                    //'                           <option value="days">days</option>',
                    '                       </select>',
                    '                   </td>',
                    '               </tr>',
                    '           </tbody>',
                    '       </table>',
                    '</div>',
                    '<div class="bd clearfix">',
                    '   <div class="ui-button clearfix cancel"><div class="left"></div><div class="mid">'+lang.label('btn_cancel')+'</div></div><div class="ui-button clearfix save"><div class="left"></div><div class="mid">'+lang.label('btn_save')+'</div></div>',
                    '</div>',
                ].join('');
        var options = {
            title: lang.label('Timer'),
            content: strHTMLTimerModal,
            id: 'modalTimerSetting',
            callBack: function(context) {
                var id = context.id, //id for saveData
                    /**
				     If you want to use timer, you should define below objTimerConfig in module.js
				     objTimerConfig: {
				    	defaultConfig: {
				    		timerUnit: ['seconds','minutes','hours','days'],
				    		timerUnitInterval:{
				    			seconds : ['60','120','180'],
				    			minutes : ['1','2','3'],
				                hours : ['12','24'],
				                days : ['1','3','5']
				    		}
				    	}
				    }
                     */
                    objTimerConfig = context.objTimerConfig,
                    val_timer_on = context.objectBox.timer.timer_on, //value from default or DB[userdata.data]
                    val_timer_unit = context.objectBox.timer.timer_unit, //value from default or DB[userdata.data]
                    val_timer_unit_interval = context.objectBox.timer.timer_unit_interval; //value from default or DB[userdata.data]
                
                return function() { // after Timer Setting WFModal Show
                	var objectContent = $$('#modalTimerSetting .modalContent'),
                	    el_timer_on = objectContent.getElement('#timer_on'),
	                	el_timer_unit = objectContent.getElement('#timer_unit'),
	            	    el_timer_unit_interval = objectContent.getElement('#timer_unit_interval');
                    WF.util.Button();
                	// set DB value or default value define in objTimerConfig to UI
                	if(val_timer_on == 1){
                		el_timer_on.set('checked', true);
                	}
                	
                	// Method use to generate [TimerUnitInterval] select element
                	// EX : arrTimerUnitInterval = ['60','120','180']
                	// EX : intMilisecondsSelected = '120000'
                	var addTimerUnitIntervalOption = function(arrTimerUnitInterval, intMilisecondsSelected){
                		var el_timer_unit_selected = el_timer_unit.getSelected()[0],
                		    intTimerUnitIntervalMiliseconds;
                		el_timer_unit_selected = el_timer_unit_selected[0] !== undefined ? el_timer_unit_selected[0] : el_timer_unit_selected;
                		
                		var strTimerUnitSelected = el_timer_unit_selected.get('value').toString(),
                		    strHtmlOption = context._getHtmlTimerUnitIntervalOption(arrTimerUnitInterval, strTimerUnitSelected, intMilisecondsSelected);
                    	el_timer_unit_interval.set('html',strHtmlOption);
                    	
                    	/* Fix Firefox14 select option selected="selected" doesn't work*/
                    	var el_timer_unit_interval_tmp = document.getElementById('timer_unit_interval');
                    	el_timer_unit_interval_tmp.selectedIndex = context._getSelectedIndexTimerUnitIntervalOption(arrTimerUnitInterval, strTimerUnitSelected, intMilisecondsSelected);
                    };
                	
                	// Method use to generate [TimerUnit] select element
                	// EX : arrTimerUnit = ['seconds','minutes','hours','days']
                	// EX : strTimerUnitSelected = 'minutes'
                    var addTimerUnitOption = function(arrTimerUnit, strTimerUnitSelected){
                    	var strTimerUnitSelected = strTimerUnitSelected !== undefined ? strTimerUnitSelected : objTimerConfig.defaultConfig.timerUnit[0],
                    		strHtmlOption = context._getHtmlTimerUnitOption(arrTimerUnit, strTimerUnitSelected);
                    	el_timer_unit.set('html',strHtmlOption);
                    	
                    	/* Fix Firefox14 select option selected="selected" doesn't work*/
                    	var el_timer_unit_tmp = document.getElementById('timer_unit');
                    	el_timer_unit_tmp.selectedIndex = context._getSelectedIndexTimerUnitOption(arrTimerUnit, strTimerUnitSelected);
                    	// trigger event change if [TimerUnit] select element change
                    	el_timer_unit.addEvent('change',function(){
                    		var strTimerUnitSelected = el_timer_unit.getSelected()[0].get('value').toString();
                    		addTimerUnitIntervalOption(objTimerConfig.defaultConfig.timerUnitInterval[strTimerUnitSelected],strTimerUnitSelected);
                    		/*Fix IE7, if dynamic set el_timer_unit_interval option, el_timer_unit_interval & el_timer_unit select box will overlap*/
                    		el_timer_unit_interval.setStyles({padding:'0','offset':{'x': 0,'y': 0}});
                    		el_timer_unit.setStyles({padding:'0','offset': {'x': 0,'y': 0}});
                    	});
                    };
                    addTimerUnitOption(objTimerConfig.defaultConfig.timerUnit, val_timer_unit);
                    addTimerUnitIntervalOption(objTimerConfig.defaultConfig.timerUnitInterval[val_timer_unit], val_timer_unit_interval);
                    
                    
                    var setDisabledTimerFrequency = function(){
                    	var is_timer_on = el_timer_on.get('checked')[0];
                    	if(is_timer_on == false){
                    		el_timer_unit.set('disabled', true);
                    		el_timer_unit_interval.set('disabled', true);
                        }else if(is_timer_on == true){
                        	el_timer_unit.set('disabled', false);
                        	el_timer_unit_interval.set('disabled', false);
                        }
                    }
                    setDisabledTimerFrequency();
                    //bind event timer_on click
                    el_timer_on.addEvent('click', function(){
                		setDisabledTimerFrequency();
                    });
                	
                    //bind event cancel button
                	objectContent.getElement('.cancel').addEvent('click', function(){
                        if (objectContent.getElement('.cancel').hasClass('disabled') != 'true'){
                            context.modalTimerSetting.close();
                        }
                    });
                	
                	//bind event save button
                	objectContent.getElement('.save').addEvent('click',function() {
                        var timer_unit = 'seconds',
                            timer_unit_interval = 0,
                            timer_on = 0;
                        
                        timer_unit = el_timer_unit.getSelected()[0].get('value').toString(),
                        timer_unit_interval = parseInt(el_timer_unit_interval.getSelected()[0].get('value').toString(),10),
                        timer_on = el_timer_on[0].get('checked') === true ? 1 : 0;
                        
                        context.objectBox.timer.timer_unit = timer_unit;
                        context.objectBox.timer.timer_on = timer_on;
                        context.objectBox.timer.timer_unit_interval = timer_unit_interval;
                        
                        context.saveData(id,'timer',{
                            onSuccess: function() {
                                context.objectBox.timer();
                            }
                        });
                        this.close();
                    }.bind(this));
            }
            }(this)
        };
        this.modalTimerSetting = new WFModal(options);
    },
    _getHtmlTimerUnitOption: function(arrTimerUnit, strTimerUnitSelected){
    	var strHtmlOption = '';
    	for(var i=0,j=arrTimerUnit.length;i<j;i++){
    		htmlSelected = (arrTimerUnit[i] == strTimerUnitSelected) ? ' selected="selected"' : '';
    		strHtmlOption += '<option value="'+arrTimerUnit[i]+'"'+htmlSelected+'>'+lang.label(arrTimerUnit[i])+'</option>';
    	}
    	return strHtmlOption;
    },
    _getSelectedIndexTimerUnitOption: function(arrTimerUnit, strTimerUnitSelected){
    	var intSelectedIndex = 0;
    	for(var i=0,j=arrTimerUnit.length;i<j;i++){
    		if(arrTimerUnit[i] == strTimerUnitSelected){
    			intSelectedIndex = i;
    			return intSelectedIndex;
    		}
    	}
    	return intSelectedIndex;
    },
    _getHtmlTimerUnitIntervalOption: function(arrTimerUnitInterval, strTimerUnitSelected, intMilisecondsSelected){
    	var strHtmlOption = '',
    	    htmlSelected = '';
    	for(var i=0,j=arrTimerUnitInterval.length;i<j;i++){
    		var intTimerUnitIntervalMiliseconds = this._timerIntervalTransformToMiliseconds(strTimerUnitSelected, arrTimerUnitInterval[i]);
    		htmlSelected = (intMilisecondsSelected !== undefined && intTimerUnitIntervalMiliseconds == intMilisecondsSelected) ? ' selected="selected"' : '';
    		strHtmlOption += '<option value="'+intTimerUnitIntervalMiliseconds+'"'+htmlSelected+'>'+arrTimerUnitInterval[i]+'</option>';
    	}
    	return strHtmlOption;
    },
    _getSelectedIndexTimerUnitIntervalOption: function(arrTimerUnitInterval, strTimerUnitSelected, intMilisecondsSelected){
    	var intSelectedIndex = 0,
    	    strHtmlOption = '',
    	    htmlSelected = '';
    	for(var i=0,j=arrTimerUnitInterval.length;i<j;i++){
    		var intTimerUnitIntervalMiliseconds = this._timerIntervalTransformToMiliseconds(strTimerUnitSelected, arrTimerUnitInterval[i]);
    		if(intMilisecondsSelected !== undefined && intTimerUnitIntervalMiliseconds == intMilisecondsSelected){
    			intSelectedIndex = i;
    			return intSelectedIndex;
            }
    	}
    	return intSelectedIndex;
    },
    _timerIntervalTransformToMiliseconds: function(strTimerUnit, intTimerUnitIntervalNotMiliseconds){
    	var timer_unit_multiple_to_miliseconds = 0;//timer interval will save miliseconds to DB, this value is determined a multiple value
    	switch(strTimerUnit){
		    case 'seconds':
		    	timer_unit_multiple_to_miliseconds = 1000;
			break;
		    case 'minutes':
		    	timer_unit_multiple_to_miliseconds = 60*1000;
			break;
		    case 'hours':
		    	timer_unit_multiple_to_miliseconds = 3600*1000;
			break;
		    case 'days':
		    	timer_unit_multiple_to_miliseconds = 86400*1000;
			break;
		}
    	return intTimerUnitIntervalNotMiliseconds*timer_unit_multiple_to_miliseconds;
    },
    onClickRefresh: function(){
    	WF.util.stopSlideShow();
        this.refreshMod();
    },
    refreshMod : function () {
    },
    onClickHelp: function(){
    	WF.util.stopSlideShow();
        var lang_path = lang.getLang();
        var url = homeBase+WF.util.getWidgetPath(this.options.name)+'/'+this.options.name+'/help/'+lang_path+'/help.html';
        var myRequest = new Request({
            url: url,
            method: 'get',
            onSuccess: function(responseText){
                var options = {
                    title: lang.label('help'),
                    content: '<iframe width="600" height="300" scrolling="auto" src="'+url+'" frameborder="0"></iframe>'
                };
                new WFModal(options);
                $$('.modalContent').setStyle('overflow-y','hidden');
            }
        }).send();
    },
    onClickClose: function(event){
    	WF.util.stopSlideShow();
        this.id = event.target.getProperty('wid');
        this.saveData( this.id, 'delete', {onResponseOK:this.closeWidget.bind(this), onResponseERR:this.closeWidgetErr.bind(this), onFailure:this.closeWidgetFailed.bind(this)});
        this.customCloseWidgetEvent(event);
    },
    closeWidget: function(text, response){
        if($chk($('sbox'+this.id))){
            if (this.objectBox.timer) {
                clearTimeout(this.objectBox.timer.tId);
                this.objectBox.timer = null;
                try {
                    delete this.objectBox.timer;
                } catch (ex) {
                }
            }
            
            $('sbox'+this.id).remove();
        }
        pgWidgets = pgWidgets-1;
        modules[this.id] = "";
        wfc_globalModules[wfc_mainScreen.currActive] = modules;
        $$('#canvas'+wfc_mainScreen.currActive+' .layout').fireEvent('autofit');
        WF.util.SaveUdata();
    },
    closeWidgetErr: function(text, response) {
        wfc_error_msg(lang.label("msg_deletewidgetfailed"));
        return;
    },
    closeWidgetFailed: function(response) {
        wfc_error_msg(lang.label("msg_deletewidgetfailed"));
        return;
    },
    getMiscData : function (id) {
        var wMiscData = wfc_widgetDataObj.getMyWMiscData(id);
        if (wMiscData === null) {
            return '';
        }
        return wMiscData;
    },
    getData: function(id) {
        var wdata = wfc_widgetDataObj.getMyWdataData(id);
        if( wdata == null ) {
            return '';
        }
        return wdata;
    },
    getParam: function(wid) {
        var strParam = wfc_widgetDataObj.getMyWdataParam(wid);
        if( strParam == null ) {
            return '';
        }
        return strParam;
    },
    getKey: function(wid) {
        var strKey = wfc_widgetDataObj.getMyWdataKey(wid);
        if( strKey == null ) {
            return '';
        }
        return strKey;
    },
    saveData: function(wid, dataStr, callback) {
        var o = {
                wfUserData : null,
                wfMiscData : null
            },
            boxData, strBoxData, s, start;
        
        if( wfc_widgetDataObj.isDataReady() ) {
            
            if (typeof dataStr !== 'string' && dataStr != undefined) {
                return;
            }
        
            if( dataStr == 'delete' ) {
                wfc_widgetDataObj.WdataDelete(wid, callback);
                return;
            }
            
            boxData = JSON.decode(this.objectBox.getProperty('data'));

            // if null, undefined, preserve saved data
            if (dataStr == undefined) {
                dataStr = html_entity_decode(boxData.data);
                if (dataStr !== '') {
                    dataStr = dataStr.slice(2, dataStr.length - 2);
                }
            }
            
            this.setMiscData();
            o.wfUserData = dataStr !== '' ? JSON.decode(dataStr) : '';
            o.wfMiscData = this.miscData;
            
            wfc_widgetDataObj.WdataUpdate(wid, JSON.encode(o), callback);

            boxData.data = '';
            s = htmlentities('[' + JSON.encode(dataStr) + ']');
            strBoxData = JSON.encode(boxData);
            start = strBoxData.indexOf('"data":"') + 8;
            strBoxData = strBoxData.substr(0, start) + s + strBoxData.substr(start);

            this.objectBox.set('data', strBoxData);
        }
    },
	setMiscData : function() {
		this.miscData = [];
		
        if (this.objectBox.timer) {
            this.miscData.push({
				id : 'timer',
                data : {
                	timer_unit: this.objectBox.timer.timer_unit,
                    timer_on: this.objectBox.timer.timer_on,
                    timer_unit_interval: this.objectBox.timer.timer_unit_interval
				}
            });
        }

        if (this.dataSources) {
            this.miscData.push({
                id : 'dataSources',
                data : this.dataSources
            });
        }
	},
    handleMiscData : function(miscData) {
		if (!miscData || !miscData.length) {
			return;
		}
		var callbacks = {
			timer : function (dbData) {
				if (typeof this.objectBox.timer !== 'function') {
					this.objectBox.timer = function(){};
				}
				this.objectBox.timer.timer_unit = dbData.timer_unit || this._getTimerUnitDefault();
				this.objectBox.timer.timer_unit_interval = dbData.timer_unit_interval || 0;
				this.objectBox.timer.timer_on = dbData.timer_on == 1 ? 1 : 0;
			},
            dataSources : function (dbData) {
                this.dataSources = dbData;
                }
            }
		
		var i = miscData.length;
		while (i--){
			if (callbacks[miscData[i].id]) {
				callbacks[miscData[i].id].call(this,miscData[i].data);
        }
		}
    },
    customCloseWidgetEvent: function(event){},
    onDragWidget: function(event){
        if(event.rightClick || event.target.hasClass('func-list-item')){
            return;
        }
        WF.util.stopSlideShow();
        var me = this;
        var moveWidget = this.objectBox;
        this.objectBox.addClass('temp');
        //create drag icon
        this.tempWidget = new Element('div', {'id':'tempWidget','styles':{'top':event.page.y-19,'left':event.page.x-25}}).injectInside(document.body);
        //init drag
        var droppables = $$('#canvas' + wfc_mainScreen.currActive + ' div.box');
        var tabDroppables = $('ui-tab').getElements('li');
        tabDroppables.pop();
        droppables.combine(tabDroppables);
        var alreadyDrop = false;
        var dragMarginOffset = 10;
        var viewSize = {
            x:(typeof document.documentElement.clientWidth !== 'undefined' ?
                document.documentElement.clientWidth :
                typeof document.body.clientWidth !== 'undefined' ? document.body.clientWidth : window.innerWidth) - dragMarginOffset,
            y:(typeof document.documentElement.clientHeight !== 'undefined' ?
                document.documentElement.clientHeight :
                typeof document.body.clientHeight !== 'undefined' ? document.body.clientHeight : window.innerHeight) - dragMarginOffset
        };
        
        if (typeof(this.objectBox.timer) === 'function') {
            clearTimeout(this.objectBox.timer.tId);
            this.objectBox.timer.timer_on = false;
        }
        
        this.myDrag = new Drag.Move(this.tempWidget, {
            'droppables': droppables,
            onDrag: function(element,obj){
				this.outside = false;
                if (obj.event.clientX <= dragMarginOffset ||
                    obj.event.clientY <= dragMarginOffset ||
                    obj.event.clientX >= viewSize.x ||
                    obj.event.clientY >= viewSize.y){
					if(this.newPosition){
						this.newPosition.remove();
						this.newPosition = '';
					}
                    moveWidget.removeClass('temp');
                    element.remove();
                    $(document).removeEvents('mouseup');
                    this.stop();
					this.outside = true;
					return;
                }
                if(this.inBox){
                    var cusorY = element.getStyle('top').split('px')[0];
                    if (!this.overed){
                        return;
                    }
                    var dWidget = this.overed.getElements('.widget');
                    for(var i=0,j=dWidget.length;i<j;i++){
                        if(dWidget[i].hasClass('temp')){
                            continue;
                        }
                        var dWidgetY = dWidget[i].getPosition().y;
                        var dWidgetHeight = dWidget[i].getSize().y-10;
                        if((cusorY-dWidgetHeight/2)>dWidgetY){
                            if(!dWidget[i].getNext('.temp')){
                                if(!this.newPosition){
                                    this.newPosition = new Element('div', {'class':'newPosition','styles':{'height':moveWidget.getSize().y-2+'px'}});
                                }
                                dWidget[i].getParent('.box').set('styles',{'height':'auto'});
                                this.newPosition.injectAfter(dWidget[i]);
                            }
                        }
                        else{
                            if(!dWidget[i].getPrevious('.temp')){
                                if(!this.newPosition){
                                    this.newPosition = new Element('div', {'class':'newPosition','styles':{'height':moveWidget.getSize().y-2+'px'}});
                                }
                                dWidget[i].getParent('.box').set('styles',{'height':'auto'});
                                this.newPosition.injectBefore(dWidget[i]);
                            }
                            break;
                        }
                    }
                }
            },
            onEnter: function(element, overed){
                if(!this.outside){
                    if(!overed.hasClass('box')){
                        this.inTab = true;
                        this.tab = overed;
                    }
                    else{
                        this.inBox = true;
                        this.overed = overed;
                        if(!overed.getLast('.widget')){
                            if(overed.getSize().y < moveWidget.getSize().y){
                                overed.set('styles',{'height':'auto'});
                            }
                            this.newPosition = new Element('div', {'class':'newPosition','styles':{'height':moveWidget.getSize().y-2+'px'}}).injectInside(overed);
                        }
                    }
                }
            },
            onLeave: function(element, overed){
                if(!overed.hasClass('box')){
                    this.inTab = false;
                }
                else{
                    this.inBox = false;
                    if(this.newPosition){
                        this.newPosition.remove();
                        this.newPosition = '';
                    }
                    overed.set('styles',{'height':overed.getParent('.row').getSize().y});
                }
            },
            onDrop: function(element, overed, event){
                if(this.inTab && this.tab.hasClass('tab_box') && !this.dTabMethod && !alreadyDrop){
                   alreadyDrop = true;
                   var tab = JSON.decode(this.tab.getElement('.tab_title').getProperty('data'));
                    var getWidgetsOfTabCallback = function(arrOriginalWidgets){
                       if(arrOriginalWidgets.length < wfc_widgetLimit){
                            var modalOption = {
                                showTitle: false,
                                onlyOverlay: true
                            };
                            this.pureOverlayModal = new WFModal(modalOption);

                            var HTML = [
                                '<tbody>',
                                '    <tr class="hd">',
                                '        <td class="left"></td>',
                                '        <td class="mid"></td>',
                                '        <td class="right"></td>',
                                '    </tr>',
                                '    <tr class="bd">',
                                '        <td class="left"></td>',
                                '        <td class="mid">',
                                '           <div>',
                                '               <a class="item" id="tab_copy" href="#">'+lang.label('tab_copy')+'</a>',
                                '               <a class="item" id="tab_move" href="#">'+lang.label('tab_move')+'</a>',
                                '           </div>',
                                '        </td>',
                                '        <td class="right"></td>',
                                '    </tr>',
                                '    <tr class="ft">',
                                '        <td class="left"></td>',
                                '        <td class="mid"></td>',
                                '        <td class="right"></td>',
                                '    </tr>',
                                '</tbody>'
                            ].join('');
                            var floatPosition = this.tab.getPosition().x+10;
                            if(floatPosition<10){
                                floatPosition = 40;
                            }
                            this.dTabMethod = new Element('table',{'html':HTML,'id':'tab_method','styles':{'left':floatPosition,'top':this.tab.getPosition().y+10}}).inject(document.body,'top');
                            var addWidget = function(event,callback){
                                event.stopPropagation();
                                var arrUdata = [];
                                var arrWdata = [];
                                var widget = JSON.decode(moveWidget.getProperty('data'));
                                var boxNumber = WF.util.getBoxNumberOfLayout(tab.columns);
                                var objFindNextBoxResult = WF.util.findNextBoxForWidgets(boxNumber, arrOriginalWidgets, 1);
                                var widget_key;
                                if(widget.widget_key){
                                    widget_key = html_entity_decode(widget.widget_key);
                                }
                                else{
                                    widget_key = '';
                                }
                                var data;
                                if(widget.data){
                                    data = html_entity_decode(widget.data);
                                }
                                else{
                                    data = '';
                                }
                                me.setMiscData();
                                if (me.miscData.length > 0) {
                                    data += '[' + JSON.encode(JSON.encode({ns:'miscData',dataArray:me.miscData})) + ']';
                                }
                                
                                var param;
                                if(widget.param){
                                    param = html_entity_decode(widget.param);
                                }
                                else{
                                    param = '';
                                }
                                arrUdata[0] = {
                                    'modname':widget.name,
                                    'column':objFindNextBoxResult.arrBoxSequence[0],
                                    'wid':pc,
                                    'page':tab.pageNumber.toString(),
                                    'order':1,
                                    'widget_key':widget_key
                                };
                                arrWdata[0] = {
                                    'modname':widget.name,
                                    'wid':pc,
                                    'data':data,
                                    'pid':tab.pageNumber,
                                    'widget_key':widget_key,
                                    'param':param
                                };
                                Cookie.set("lastID", pc-1, {path: wf_cookie_path});
                                var AddCallBack = function(){
                                    if(callback){
                                        WF.util.SaveUdata(true);
                                    }
                                    else{
                                        window.location.reload();
                                    }
                                };
                                sendData(dbHandler, JSON.encode({act:'addWidgets', pid:tab.pageNumber, udata:arrUdata, wdata:arrWdata, updatedOriginalUdata:objFindNextBoxResult.arrUpdatedOriginalUdata}), AddCallBack);
                                arrUdata = null;
                                arrWdata = null;
                                objFindNextBoxResult.arrBoxSequence = null;
                                objFindNextBoxResult.arrUpdatedOriginalUdata = null;
                                objFindNextBoxResult.arrAddWidgetNumberOfBox = null;
                                objFindNextBoxResult = null;
                            }.bind(this);
                            $('tab_move').addEvent('click',function(event){
                                event.preventDefault();
                                this.dTabMethod.destroy();
                                var callback = function(){};
                                var wid = JSON.decode(moveWidget.getProperty('data')).wid;
                                var closeWidget = function(){
                                    if($chk($('sbox'+wid))){
                                        $('sbox'+wid).remove();
                                    }
                                    pgWidgets = pgWidgets-1;
                                    modules[wid] = "";
                                    wfc_globalModules[wfc_mainScreen.currActive] = modules;
                                    $$('#canvas'+wfc_mainScreen.currActive+' .layout').fireEvent('autofit');

                                    addWidget(event,true);
                                };
                                me.saveData( wid, 'delete', {onResponseOK:closeWidget});

                            }.bind(this));
                            $('tab_copy').addEvent('click',function(event){
                                event.preventDefault();
                                this.dTabMethod.destroy();
                                addWidget(event);
                            }.bind(this));
                            $(document).addEvent('click',function(event){
                                this.dTabMethod.destroy();
                                this.pureOverlayModal.close();
                                $(document).removeEvents('click');
                                $(document).removeEvents('keydown');
                            }.bind(this));
                            $(document).addEvent('keydown', function(event){
                                if (event.key == 'esc') {
                                    this.dTabMethod.destroy();
                                    $(document).removeEvents('click');
                                    $(document).removeEvents('keydown');
                                }
                            }.bind(this));
                        }else{
                            if ($$('#message div[name="widgetNoMoreThan20"]').length == 0){
                                var option = {
                                    type: '0', //0 error, 1 warning, 2 info
                                    description: lang.label('widget_maximum_number_1')+wfc_widgetLimit+lang.label('widget_maximum_number_2'),
                                    name: 'widgetNoMoreThan20',
                                    close: true
                                };
                                wfc_message.fireEvent('message',option);
                            }
                        }
                        alreadyDrop = false;
                    };
                    WF.util.getWidgetsOfTab(tab.pageNumber, getWidgetsOfTabCallback.bind(this));
                }
                else if(this.newPosition){
                    //before resize widget, set widget title to default width
                    moveWidget.injectBefore(this.newPosition);
                    WF.util.InitWidget(moveWidget);
                    this.newPosition.remove();
                    this.newPosition = '';
                    if (moveWidget.get('sHeight') != null){
                        moveWidget.fireEvent('widget_resize',moveWidget);
                        $$('#canvas'+wfc_mainScreen.currActive+' .layout').fireEvent('autofit');
                    }
                    //after move to new box, refresh widget title width
                    WF.util.RefreshWidgetTitleEllipsis(moveWidget);
                    WF.util.SaveUdata();
                }
                
                if (typeof(me.objectBox.timer) === 'function') {
                    me.objectBox.timer.timer_on = true;
                    me.objectBox.timer();
                }
            },
            onComplete: function(element,event){
            },
            onCancel: function(){
            }
        });
        this.myDrag.start(event);
        $(document).addEvent('mouseup',function(){
            this.objectBox.removeClass('temp');
            this.tempWidget.remove();
            $(document).removeEvents('mouseup');
            this.myDrag.stop(event);
        }.bind(this));
    },
    onDropWidget: function(event){
    },
    //request method
    MochaModalCallBack:function(modal){
        var settingsBoxPtr=this.settingsBox;
        if(settingsBoxPtr)
        {
            if(modal)
            {
                settingsBoxPtr.injectInside(modal.contentEl);
            }
            settingsBoxPtr.setStyle('display','block');
            settingsBoxPtr.removeClass('window_setting');
        }
    },
    fillTitle: function(htmlData){
        //Handle old modal window
        if(this.options.modal == true)
        {
            this.boxTitle=$(this.ttlid);
        }
        if($defined(this.boxTitle))
        {
            /*
            if(this.options.hasIcon) {
                var imgURL =homeBase+WF.util.getWidgetPath(this.options.name)+'/'+this.options.name+'/img/ico.gif';

                var tester=new Image();
                tester.src=imgURL;

                if(tester.complete)
                    htmlData = '<img align="left" src="'+ imgURL +'"> &nbsp;'+htmlData;
            }
            */
            var width = this.boxTitle.getStyle('width');
            this.boxTitle.destroy();
            this.boxTitle = new Element('div', {'class':'title ellipsis','styles':{'width':width},'html':htmlData,'title':html_entity_decode(htmlData)}).injectInside(this.boxHD);
        }
    },
    getContentSize: function(){
        //get correct tab when layout resize
        var dTab = $$('#tab_box'+this.pageNumber+' .tab_title')[0];
        var data = JSON.decode(dTab.getProperty('data'));
        var dHeight = this.options.defaultWidgetHeight;
        if(data.autoFit == '1'){
            var dWidget = this.objectBox.getParent('.box').getElements('.widget');
            if(dWidget.length == 1){ //if widget number == 1
                this.objectBox.addClass('hide');
                if(this.objectBox.getProperty('sHeight') === null){
                    var sHeight = dHeight; //set a default sHeight if sHeight is null
                }else{
                    var sHeight = this.objectBox.getProperty('sHeight').toInt();
                }
                var boxHeight = this.objectBox.getParent('.box').getSize().y;
                this.objectBox.removeClass('hide');
                var realHeight = sHeight+10+(this.widgetContent.getSize().y - this.boxBD.getSize().y);
                if(realHeight>boxHeight){
                    boxHeight = realHeight;
                }
                var height = boxHeight -this.boxHD.getSize().y-this.boxFT.getSize().y-9-10-(this.widgetContent.getSize().y - this.boxBD.getSize().y);
            }else{ //if widget number > 1
                if(this.objectBox.getProperty('sHeight') === null){
                	var height = dHeight;
                }else{
                    var height = this.objectBox.getProperty('sHeight')-this.boxHD.getSize().y-this.boxFT.getSize().y-9;
                }
            }
        }
        else{ //if autoFix = false
            if(this.objectBox.getProperty('sHeight') === null){
                var height = dHeight;
            }else{
                var height = this.objectBox.getProperty('sHeight')-this.boxHD.getSize().y-this.boxFT.getSize().y-9;
            }
        }

        // intXAdjust is to Fix ie7 resize box width, widgetContent overlap and blank drag bar
        // if no intXAdjust, getContentSize will get more 2px, and widgetContent will show scrollbar
        var intXAdjust = 0;
        if (Browser.ie7){
        	intXAdjust = 2;
        }
        var xy = {
            'x': this.objectBox.getParent('.box').getSize().x-16-intXAdjust,
            'y': height
        };
        return xy;
    },
    proxyRequest: function(data, onSuccess, onFailure){
    	var pool_id,
		    myoptions = {useJSON:false,async:true}; //default myoptions
    	// Fix memory and handler leak issue
    	// Step 1 : if data got pool_id=unique_id, EX : module=modSimple&serverid=1&pool_id=TimerLog4, means turn of pool proxyRequest
    	if(data.indexOf("pool_id=") != -1){
    		var arrsKeyVal = data.split("&"),
    		    arrKeyVal;
    		for(var i=0,j=arrsKeyVal.length;i<j;i++){
    			if(arrsKeyVal[i].indexOf("pool_id=") != -1){
    				arrKeyVal = arrsKeyVal[i].split("=");
    				pool_id = arrKeyVal[1];
    			}
    		}
    		// retrieve pool_id as set to myoptions
    		if(pool_id){
    			myoptions = {useJSON:false,async:true,pool_id:pool_id};
    		}
    	}
        wfc_ProxyObj.fetch(data, myoptions, {onSuccess:onSuccess, onFailure:onFailure});
    },
    showMessage: function(message, type, container){
        var inWidget = false;
        if(!container){
            this.widget_message_container = this.boxBD.getElement('.widget_message');
            if(!this.widget_message_container){
                this.widget_message_container = new Element('div',{'class':'widget_message'}).inject(this.boxBD,'top');
            }
            inWidget = true;
            this.widget_message = new WFMessage(this.widget_message_container); // widget message
        }
        else{
            this.server_message = new WFMessage(container); // server setting message
        }
        var option = {
            type: type,
            description: message,
            button: '',
            callback: function(){},
            close: false
        };
        if(inWidget){
            this.widget_message.fireEvent('message',option);
        }
        else{
            this.server_message.fireEvent('message',option);
        }

        if(inWidget && !this.noReload){
            window.fireEvent('widget_load', this.widgetInfo);
        }
    },
    serverSetting: function(){
        var HTML = [
            '<div id="serverSetting_message"></div>',
            '<div class="hd">',
            '   <div class="servers"></div>',
            '</div>',
            '<div class="bd clearfix">',
            '   <div class="check"><a href="#" class="check_server">'+lang.label('check_server')+'</a></div>',
            '   <div class="ui-button clearfix cancel">',
            '       <div class="left"></div>',
            '       <div class="mid">'+lang.label('btn_cancel')+'</div>',
            '   </div>',
            '   <div class="ui-button clearfix save">',
            '       <div class="left"></div>',
            '       <div class="mid">'+lang.label('btn_save')+'</div>',
            '   </div>',
            '</div>'
        ].join('');

        var options = {
            id: 'modalServerSetting',
            title: lang.label('widget_setting'),
            content: HTML,
            onClose:this.cancelRequest.bind(this),
            callBack: function(){
                var objectContent = $$('#modalServerSetting .modalContent');
                var serverSetting_message = $('serverSetting_message');
                var div = objectContent.getElement('.hd .servers')[0];
                
                this._buildServerList();
                var tbl = this._buildServerListTable();
                tbl.inject(div);

                //bind event
                WF.util.Button();
                if ($$('#modalServerSetting .modalContent .serverlist .checkbox input').length > 0){
                    $$('#modalServerSetting .modalContent .ui-button.save').addClass('disable');
                }
                var saveBtn = objectContent.getElement('.save')[0];
                if (saveBtn) {
                    saveBtn.addEvent('click', function(){
                    if ($$('#modalServerSetting .modalContent .ui-button.save').hasClass('disable') == 'true'){
                        return;
                    }
                    $$('#modalServerSetting .modalContent .ui-button.save').addClass('disable');
                    objectContent.getElement('.cancel').addClass('disabled');
                        var list = {},
                            listcount = 0,
                            dataSources = {},
                            item, o, ds;
                        
                        for (var i=0,j=this.serverList.length; i<j; ++i) {
                            item = this.serverList[i];
                            if (item.selected == '1') {
                                listcount++;
                                list[item.id] = item.hostinfo;
                                o = {
                                    serverid : item.id,
                                    host : item.hostinfo     
                                },
                                ds = dataSources[item.type];
                                (ds) ? ds.push(o) : (dataSources[item.type] = [o]);
                        }
                    }
                        if (listcount == 0) {
                        this.showMessage(lang.label('at_least_one_server'),0,serverSetting_message);
                        objectContent.getElement('.save').removeClass('disable');
                        objectContent.getElement('.cancel').removeClass('disabled');
                        return;
                    }
                        if (listcount >= warningservercount) {
                        var answer = confirm(lang.labelText("add_too_many_servers"));
                        if (!answer) {
                            objectContent.getElement('.save').removeClass('disable');
                            objectContent.getElement('.cancel').removeClass('disabled');
                            return;
                        }
                    }
                        
                        this.dataSources = dataSources;

                        this.saveData(this.id, null, {
                        onSuccess: function(responseObj){
                            var jsonObj = responseObj[1];
                            if (jsonObj.errcode != 0) {
                                this.showMessage(lang.label("save_widget_server_setting_failed") + "<br>" + lang.label("errorcode_" + jsonObj.errcode),0,serverSetting_message);
                                objectContent.getElement('.save').removeClass('disable');
                                objectContent.getElement('.cancel').removeClass('disabled');
                            }
                            else {
                                    this.saveServer = list;
                                this.serverSettingModal.close();
                                this.refreshMod();
                            }
                        }.bind(this),
                        onFailure: function(){
                            this.showMessage(lang.label("save_widget_server_setting_failed") + "<br>" + lang.label("widget_server_timeout_connect"),0,serverSetting_message);
                            objectContent.getElement('.save').removeClass('disable');
                            objectContent.getElement('.cancel').removeClass('disabled');
                        }.bind(this)
                    });
                }.bind(this));
                }
                var cancelBtn = objectContent.getElement('.cancel')[0];
                if (cancelBtn) {
                    cancelBtn.addEvent('click', function(){
                    if (objectContent.getElement('.cancel').hasClass('disabled') != 'true'){
                        this.cancelRequest();
                        this.serverSettingModal.close();
                    }
                }.bind(this));
                }
                var chkServerBtn = objectContent.getElement('.bd .check_server')[0];
                if (chkServerBtn) {
                    chkServerBtn.addEvent('click', function(event){
                    event.preventDefault();
                    this.cancelRequest();
                    this.serverSettingModal.close();
                    $('server_visib').fireEvent('click',event);
                }.bind(this));
                }
            }.bind(this)
        };
        this.serverSettingModal = new WFModal(options);
    },
    checkConnectionStatus: function(id, obj){
        var requestinfo = "act=check&module="+obj.type+"&serverid=" + id;
        var serverSettingRequestObj = wfc_ProxyObj.fetch(requestinfo, {
            useJSON: false,
            async: true
        },
        {
            onSuccess: function(response){
                var response = JSON.decode(response);
                if(response&&response.errcode == 0){
                    obj.connected = 1;
                    $$('#modalServerSetting .modalContent .serverlist #'+obj.id+' .server img').set('src',homeBase + 'img/default/server_online_16.gif');
                    $$('#modalServerSetting .modalContent .serverlist #'+obj.id+' .server img').set('title',lang.label('online'));
                    $$('#modalServerSetting .modalContent .serverlist #'+obj.id+' .checkbox input').set('disabled',false);
                }
                else{
                    obj.connected = 0;
                    $$('#modalServerSetting .modalContent .serverlist #'+obj.id+' .server img').set('src',homeBase + 'img/default/server_offline_16.gif');
                    $$('#modalServerSetting .modalContent .serverlist #'+obj.id+' .server img').set('title',lang.label('offline'));
                    $$('#modalServerSetting .modalContent .serverlist #'+obj.id+' .checkbox input').set('disabled',false);
                }
                var serverCheckbox = $$('#modalServerSetting .modalContent .serverlist .checkbox input');
                var isDisableServerButton = false;
                serverCheckbox.each(function(item, index){
                    if(item.get('disabled')){
                        isDisableServerButton = true;
                    }
                });

                if(isDisableServerButton){
                    $$('#modalServerSetting .modalContent .ui-button.save').addClass('disable');
                }else{
                    $$('#modalServerSetting .modalContent .ui-button.save').removeClass('disable');
                }
            }.bind(this),
            onFailure: function(response){
                if(response&&response.isTimeout == true) {
                    obj.connected = 2;
                }
                else{
                    obj.connected = 0;
                }
                $$('#modalServerSetting .modalContent .serverlist #'+obj.id+' .server img').set('src',homeBase + 'img/default/server_offline_16.gif');
                $$('#modalServerSetting .modalContent .serverlist #'+obj.id+' .server img').set('title',lang.label('offline'));
                $$('#modalServerSetting .modalContent .serverlist #'+obj.id+' .checkbox input').set('disabled',false);
                var serverCheckbox = $$('#modalServerSetting .modalContent .serverlist .checkbox input');
                var isDisableServerButton = false;
                serverCheckbox.each(function(item, index){
                    if(item.get('disabled')){
                        isDisableServerButton = true;
                    }
                });

                if(isDisableServerButton){
                    $$('#modalServerSetting .modalContent .ui-button.save').addClass('disable');
                }else{
                    $$('#modalServerSetting .modalContent .ui-button.save').removeClass('disable');
                }
            }.bind(this)
        });
         this.arrServerSettingRequest.push(serverSettingRequestObj);
    },
    renderComponent: function(arrComponentSettings, arrComponentStatus, arrActivatedComponentNames, options){
        this.components = [];
        if (options.executeBeforeRender){
            options.executeBeforeRender.each(function(event, index){
                event();
            }.bind(this));
        }            
        arrComponentSettings.each(function(component, index){
            var objWidgetComponentFn = new Function("parentNodeSelector", "data","componentStatus", "arrActivatedComponentNames",
                " return new "+component.wcomponent_name+"(parentNodeSelector, data, componentStatus, arrActivatedComponentNames);");
            var objWidgetComponent;
            if (arrComponentStatus){
                objWidgetComponent = objWidgetComponentFn(options.parentNodeSelector, component, arrComponentStatus[index], arrActivatedComponentNames);
            }else{
                objWidgetComponent = objWidgetComponentFn(options.parentNodeSelector, component, arrComponentStatus, arrActivatedComponentNames);
            }
            this.components.push(objWidgetComponent);
        }.bind(this));

        if (options.callbacks){
            options.callbacks.each(function(callback, index){
                callback();
            }.bind(this));
        }
    },
    renderComponentList: function(arrComponentSettings, arrComponentStatus, arrActivatedComponentNames, options){
        if(arrComponentSettings.length > 0){
            var arrTempComponentNames = [];
            arrComponentSettings.each(function(setting){
                var componentName = setting.wcomponent_name;
                if(!wfc_component_list.contains(componentName)){
                    arrTempComponentNames.push(componentName);
                }
            });

            if (arrTempComponentNames.length > 0){
                var intAssetLoadedCount = 0;
                var that = this;
                arrTempComponentNames.each(function(componentName, i){
                    Asset.javascript(WP_WEBROOT_NO_SLASH+'/widgetComponent/'+componentName+'/component.js', {
                        onload: function(){
                            if(!wfc_component_list.contains(componentName)){
                                wfc_component_list.push(componentName);
                                intAssetLoadedCount++;
                                if (intAssetLoadedCount == arrTempComponentNames.length){
                                    that.renderComponent(arrComponentSettings, arrComponentStatus, arrActivatedComponentNames, options);
                                }
                            }
                        }
                    });
                });
            }else{
                this.renderComponent(arrComponentSettings, arrComponentStatus, arrActivatedComponentNames, options);
            }
        }
    }, 
    _buildSaveServer : function (dataSources) {
        if (typeof dataSources !== 'object') {
            return;
        }
        this.saveServer = {};
        for (var prop in dataSources) {
            if (dataSources.hasOwnProperty(prop)) {
                var a = dataSources[prop];
                for (var i=0,j=a.length;i<j;++i) {
                    this.saveServer[a[i].serverid] = a[i].host;
                }
            }
        }
        return true;
    },
    _buildServerList : function () {
        this.serverList = [];
                
        var list = g_serverlist.getServerList(),
            currenttime = new Date().getTime();

        if (!this._buildSaveServer(this.dataSources) && !this.saveServer) {
            this.saveServer = {};
        }
        
        if (custom_options && custom_options.hide_localhost){
            for (var i=0,j=list.length;i<j;++i){
                if (list[i].name === 'localhost'){
                    break;
                }
            }
            if (i<j){
                list.splice(i,1);
            }
        }
        
        if (this.options.supportServerTypes && this.options.supportServerTypes.length > 0){
            for (var i=0,j=list.length; i<j; i++) {
                var diff = currenttime - parseInt(list[i].lastcheck);
                var needtocheck = ((diff / 1000) > (60 * 10)) || (diff < 0);
                for (var x=0,y=this.options.supportServerTypes.length;x<y;++x){
                    if (list[i].hostinfo.type === this.options.supportServerTypes[x]){
                        this.serverList.push({
                            name: list[i].name,
                            hostinfo: (list[i].id == "1") ? list[i].name: list[i].hostinfo.host,
                            type: list[i].hostinfo.type,
                            selected: $chk(this.saveServer[list[i].id]) ? 1 : 0,
                            connected: (!needtocheck) ? 1 : -1,
                            id: list[i].id
                        });
                        this.checkConnectionStatus(list[i].id, this.serverList[this.serverList.length - 1]);
                    }
                }
            }
        }
    }, 
    _buildServerListTable : function () {
        var table = new Element('table', {
            id : 'server_list',
            'class' : 'serverlist',
            html : [
                '<tbody>',
                '   <tr>',
                '       <th class="check">'+lang.label('select')+'</th>',
                '       <th class="title">'+lang.label('cloud_url')+'</th>',
                '       <th class="type">'+lang.label('type')+'</th>',
                '   </tr>',
                '</tbody>'
            ].join('')
        });
        
        if (this.serverList.length > 0) {
            Array.each(this.serverList, function(item, index){
                if (custom_options.hide_localhost && item.name === 'localhost'){
                    return;
                }
                var row = table.insertRow(table.rows.length);
                row.id = item.id;
                var status;
                var icon;
                if (item.connected == "1") {
                    status = 'online';
                    icon = '<img class="status_img" src="' + homeBase + 'img/default/server_online_16.gif" title="' + lang.label(status) + '">';
                }
                else if (item.connected == "0" || item.connected == "2") {
                    status = 'offline';
                    icon = '<img class="status_img" src="' + homeBase + 'img/default/server_offline_16.gif" title="' + lang.label(status) + '">';
                }
                else {
                    icon = '<img class="status_img" src="' + homeBase + 'img/default/widgetLoading.gif">';
                }
                var td_1 = new Element('td',{'class':'checkbox'}).inject(row);
                var ipTip = changeLineForTip(item.name, 70);
                var td_2 = new Element('td',{'class':'server','html':icon+'<div class="ip ellipsis" title="'+ipTip+'">'+item.name+'</div>'}).inject(row);
                var td_3 = new Element('td',{'html':lang.label(item.type)}).inject(row);
                var chk = new Element('input', {
                    'type': 'checkbox',
                    'name': 'selectServer',
                    'checked': (item.selected)? true : false,
                    'disabled': true
                }).injectInside(td_1);
                chk.checked = (item.selected) ? true : false;
                chk.addEvent('change', function() {
                    if(this.checked){
                        item.selected = "1";
                    }
                    else{
                        item.selected = "0";
                    }
                });
            });
        }
        
        return table;
    }    
});
